package ferp.android.views.table.element.misere;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import ferp.android.R;
import ferp.android.managers.DeckManager;
import ferp.core.card.Card;
import ferp.core.game.Settings;
import ferp.core.player.Hand;

import java.util.List;

/**
 * User: olegs
 * Date: 25/02/12 00:31
 */
public class MisereDeskView extends RelativeLayout
{
  public MisereDeskView(Context context)
  {
    super(context, null);

    // inflate a layout
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.misere_desk, this, true);

    // cache rows
    Resources resources = getResources();
    int i = 0;

    for (Card.Suit s : Card.Suit.rising)
      rows[i++] = new Row(context, resources, s);
  }
  
  public void reset()
  {
    setVisibility(INVISIBLE);

    for (Row r : rows)
      r.reset();
  }
  
  public void set(int hash, Settings.RankOrder order)
  {
    List<Card> cards = Hand.cards(hash, Card.Suit.risingAsList, order, true);

    for (Card c : cards)
      rows[c.suit.ordinal()].set(c);

    switchOrder(order);
  }

  public void switchOrder(Settings.RankOrder order)
  {
    for (Row r : rows)
      r.set(order);
  }

  public void mark(Card c) {rows[c.suit.ordinal()].mark(c.rank);}

  // id prefixes
  private final static String MISERE = "misere_";
  private final static String SUIT   = MISERE + "suit_";
  private final static String ROW    = MISERE + "row_";
  private final static String RANK   = MISERE + "rank_";

  // row widgets
  private final class Row implements DeckManager.RefreshableView
  {
    @Override
    public void refresh()
    {
      DeckManager dm = DeckManager.instance(getContext());

      image.setImageDrawable(dm.getSuitImage(suit, true));
    }

    private final class Ranks
    {
      private Ranks(Context context, Resources resources, Card.Suit suit, Settings.RankOrder order)
      {
        layout = (LinearLayout)findViewById(resources.getIdentifier(ROW + suit.shortName() + "_" + order.toString().toLowerCase(), "id", context.getPackageName()));

        for (Card.Suit s : Card.Suit.rising)
          for (Card.Rank r : Card.Rank.rising)
            views[r.ordinal()] = (TextView)layout.findViewById(resources.getIdentifier(RANK + Card.card(s, r).rank, "id", context.getPackageName()));
      }

      private void reset()
      {
        for (TextView tv : views)
          tv.setVisibility(GONE);
      }

      private void mark(Card.Rank r)
      {
        views[r.ordinal()].setTextColor(COLOR_CARD_PLAYED);
      }

      private void set(Card c)
      {
        TextView tv = views[c.rank.ordinal()];

        tv.setTextColor(c.suit == Card.Suit.SPADES || c.suit == Card.Suit.CLUBS ? Color.BLACK : Color.RED);
        tv.setVisibility(VISIBLE);
      }

      // played card color
      private static final int COLOR_CARD_PLAYED = 0xFFBEBEBE;

      private LinearLayout layout;
      private TextView[] views = new TextView[Card.Rank.rising.length];
    }

    // row's suit
    private Card.Suit suit;
    // suit image
    private ImageView image;

    // ranks
    private final Ranks ascending;
    private final Ranks descending;

    private Row(Context context, Resources resources, Card.Suit suit)
    {
      this.suit = suit;
      this.image = (ImageView)findViewById(resources.getIdentifier(SUIT + suit.shortName(), "id", context.getPackageName()));

      ascending = new Ranks(context, resources, suit, Settings.RankOrder.ASCENDING);
      descending = new Ranks(context, resources, suit, Settings.RankOrder.DESCENDING);

      DeckManager.instance(context).register(this);
    }

    private void reset()
    {
      ascending.reset();
      descending.reset();
    }

    private void mark(Card.Rank r)
    {
      ascending.mark(r);
      descending.mark(r);
    }

    private void set(Card c)
    {
      ascending.set(c);
      descending.set(c);
    }

    private void set(Settings.RankOrder order)
    {
      switch (order)
      {
        case ASCENDING:
          update(ascending, descending);
          break;

        case DESCENDING:
          update(descending, ascending);
          break;
      }
    }

    private void update(Row.Ranks show, Row.Ranks hide)
    {
      hide.layout.setVisibility(GONE);
      show.layout.setVisibility(VISIBLE);
    }
  }

  private final Row[] rows = new Row[Card.Suit.rising.length];
}
